/**
 * @license
 * Copyright 2021 Du Tian Wei
 * SPDX-License-Identifier: Apache-2.0
 */
(function () {
    const ROOT_URL = "../jsruntime/test/";
    const PAGE_URL = "index.html";
    let windows = [];
    let window_sn = 0;
    let jspreviewer;
    let browser_run_window;
    function standaloneWindow() {
        if ((!browser_run_window) || browser_run_window.closed) {
            browser_run_window = window.open(ROOT_URL + PAGE_URL, 'ob_run_window');
        }

        OpenBlock.exportExePackage((err, result) => {
            if (!err) {
                let assets = {};
                let arr_assets = [];
                let datas = VFS.partition.assets._storage.datas
                for (let key in datas) {
                    let d = datas[key].slice(0);
                    assets[key] = d;
                    arr_assets.push(d);
                }
                let runProjectCmd = { "cmd": "runProject", "bytes": result, fsm: "Start.Main", assets };
                browser_run_window.postMessage(runProjectCmd, arr_assets);
            }
        });
    }
    function newWindow(result) {
        let assets = {};
        let arr_assets = [];
        let datas = VFS.partition.assets._storage.datas
        for (let key in datas) {
            let d = datas[key].slice(0);
            assets[key] = d;
            arr_assets.push(d);
        }
        let runProjectCmd = { "cmd": "runProject", "bytes": result, fsm: "Start.Main", assets };
        let sn = ++window_sn;
        let w = {
            id: sn, enable: true, style: { width: '375px', height: '640px' },
            gridX: 0, gridY: 0, iframe: null,
            mousePosition: { x: 0, y: 0 },
            msg: null,
            showLog: true
        };
        let index = windows.length;
        w.onVisibleChange = function (v) {
            setTimeout(() => {
                windows.splice(index, 1);
                w.iframe.remove();
                // windows[index] = null;
            }, 5);
        };
        windows.push(w);
        setTimeout(() => {
            let iframes = jspreviewer.$refs.jsprevieweriframe;
            let iframe = iframes[iframes.length - 1];
            w.iframe = iframe;
            iframe.contentWindow.window.onload = () => {
                iframe.contentWindow.postMessage(runProjectCmd, arr_assets);
            };
            iframe.contentWindow.postMessage(runProjectCmd, arr_assets);
            jspreviewer.dragData.push(jspreviewer.$refs.jspreviewerinst[iframes.length - 1].$vnode.componentInstance._data.dragData);
        }, 0);
    }
    Vue.component('jspreviewer_add', {
        props: [],
        data: {},
        template: '<span>\
        <tooltip\
            content="独立窗口运行" :delay="800">\
            <a class="headerBtn">\
                <icon type="ios-browsers" @click="runInStandaloneWindow" size="20"\
                    style="cursor:pointer;vertical-align: -2px;"></icon>\
            </a>\
        </tooltip>\
        <tooltip\
            content="新预览窗口" :delay="800">\
            <a class="headerBtn">\
                <icon type="ios-apps" @click="newWindow" size="20"\
                    style="cursor:pointer;vertical-align: -2px;"></icon>\
            </a>\
        </tooltip>\
        <!--<tooltip\
            content="调试" :delay="800">\
            <a class="headerBtn">\
                <icon type="md-bug" @click="newDebugWindow" size="20"\
                    style="cursor:pointer;vertical-align: -2px;"></icon>\
            </a>\
        </tooltip>-->\
        </span>',
        methods: {
            newWindow() {
                OpenBlock.exportExePackage((err, result) => {
                    if (!err) {
                        newWindow(result);
                    }
                });
            },
            runInStandaloneWindow() {
                if (this.loading) {
                    UB_IDE.$Message.info(OpenBlock.i('正在打开工程，请稍后。'));
                    return;
                }
                UB_IDE.saveAll();
                standaloneWindow();
            },
            newDebugWindow() {
                OpenBlock.exportExePackage({ debug: true }, (err, result) => {
                    if (!err) {
                        newWindow(result);
                    }
                });
            }
        }
    });
    Vue.component('jspreviewer', {
        props: [],
        data() {
            return {
                enable: true,
                dragData: [],
                windows
            };
        },
        template: '\
        <template>\
        <div>\
        <modal v-for="(win,index) in windows"\
         :key="win.id" @on-visible-change="windows[index].onVisibleChange" \
         class="jspreviewer" ref="jspreviewerinst" :mask-closable="false" :mask="false"\
         footer-hide draggable v-model="win"  :title="OpenBlock.i(\'Simulator\')+\'-\'+win.id" \
         :width="win.style.width"\
         closable="false" transfer="false">\
            <select name="screen" class="screen-select" ref="jsprevieweriframe_screen"\
             @change="changeScreen(win,$event)">\
                <option value="666px">1333 9:16</option>\
                <option selected value="640px">1280</option>\
                <option value="600px">1200 10:16</option>\
                <option value="500px">1000 4:3</option>\
                <option value="375px">750 1:1</option>\
                <option value="281px">562 3:4</option>\
                <option value="234px">468 16:10</option>\
                <option value="210px">421 16:9</option>\
            </select>\
            <tooltip :content="OpenBlock.i(\'重启\')" :delay="500">\
            <i-button size="small"  @click="restart(win)">R</i-button>\
            </tooltip>\
            <tooltip :content="OpenBlock.i(\'显示日志\')" :delay="500">\
            <input type="checkbox" checked @change="showLogChange(win)" v-bind="win.showLog"/>\
            </tooltip>\
            <tooltip :content="OpenBlock.i(\'清除日志\')" :delay="500">\
            <i-button size="small"  @click="clearLog(win)">C</i-button>\
            </tooltip>\
        {{OpenBlock.i(\"Grid\")}} <i-input number @on-change="gridChange(win)" style="width:40px" v-model="win.gridX"/>:<i-input number @on-change="gridChange(win)" style="width:40px" v-model="win.gridY"/>\
        <span style="display:inline-block;width:30px">{{win.mousePosition.x}}</span>,<span style="display:inline-block;width:30px">{{win.mousePosition.y}}</span>\
        <!-- <i-button size="small" @click="pause(win)">{{OpenBlock.i("pause")}}</i-button>\
        <i-button size="small" @click="resume(win)">{{OpenBlock.i("resume")}}</i-button> -->\
        <Alert v-if="win.msg" :type="win.msg.type">{{OpenBlock.i(win.msg.content)}}</Alert>\
        <div class="jspv_wrap" :style="win.style"><iframe ref="jsprevieweriframe" class="jsprevieweriframe" scrolling="no"\
         src="' + ROOT_URL + PAGE_URL + '"\
         >\
        </frame></div>\
        </modal>\
    </div>\
    </template>',
        mounted() {
            jspreviewer = this;
            this.$watch('dragData', function (newValArr, oldVal) {
                newValArr.forEach(newVal => {
                    if (!newVal.dragging) {
                        if (newVal.y < 0) {
                            newVal.y = 0;
                        }
                        if (newVal.x < -300) {
                            newVal.x = -300;
                        }

                        if (newVal.y > window.innerHeight - 100) {
                            newVal.y = window.innerHeight - 100;
                        }
                        if (newVal.x > window.innerWidth - 100) {
                            newVal.x = window.innerWidth - 100;
                        }

                    }
                });
            }, { deep: true, immediate: true });
        },
        methods: {
            showLogChange(win) {
                win.showLog = !win.showLog;
                let runProjectCmd = {
                    "cmd": "showLog",
                    value: win.showLog
                };
                win.iframe.contentWindow.postMessage(runProjectCmd);
            },
            closeSimular(win, index) {
                console.log(win, index);
            },
            changeScreen(win, evt) {
                win.style.height = evt.target.value;
            },
            restart(win) {
                let runProjectCmd = {
                    "cmd": "restart",
                    fsm: "Start.Main"
                };
                win.iframe.contentWindow.postMessage(runProjectCmd);
            },
            clearLog(win) {
                let runProjectCmd = {
                    "cmd": "clearLog"
                };
                win.iframe.contentWindow.postMessage(runProjectCmd);
            },
            pause(win) {
                let runProjectCmd = {
                    "cmd": "pause"
                };
                win.iframe.contentWindow.postMessage(runProjectCmd);
            },
            resume(win) {
                let runProjectCmd = {
                    "cmd": "resume"
                };
                win.iframe.contentWindow.postMessage(runProjectCmd);
            },
            gridChange(win) {
                let arg = { x: Math.abs(parseInt(win.gridX)), y: Math.abs(parseInt(win.gridY)) };
                let drawGrid = {
                    "cmd": "drawGrid",
                    "arg": arg
                };
                win.iframe.contentWindow.postMessage(drawGrid);
                console.log(arg);
            }
        }
    });
    OpenBlock.onInited(() => {
        class Simulator extends OBConnector {
            pageUrl;
            loading = false;
            /**
             * @type {Window}
             */
            constructor() {
                super();
                this.pageUrl = "../jsruntime/test/index.html";
            }
            setLoading() {
                this.loading = true;
            }
            unsetLoading() {
                this.loading = false;
            }
            loadConfig() {
                Simulator.loadDefaultConfig();
            }
            static loadDefaultConfig() {
                let env = ROOT_URL + 'env/'
                let jsarr = [
                    env + 'i18n_zh.js',
                    env + 'nativeEvent.js',
                    env + 'native.js',
                ];
                var xmlpath = env + "nativeBlocks.xml";
                OpenBlock.loadNativeInfo(jsarr, xmlpath);
            }
            runProject() {
                if (this.loading) {
                    UB_IDE.$Message.info(OpenBlock.i('正在打开工程，请稍后。'));
                    return;
                }
                let assets = {};
                let arr_assets = [];
                let datas = VFS.partition.assets._storage.datas
                for (let key in datas) {
                    let d = datas[key].slice(0);
                    assets[key] = d;
                    arr_assets.push(d);
                }
                OpenBlock.exportExePackage((err, result) => {
                    if (!err) {
                        let runProjectCmd = {
                            "cmd": "runProject",
                            "bytes": result,
                            fsm: "Start.Main",
                            assets
                        };
                        if (windows.length == 0) {
                            newWindow(result);
                        }
                        setTimeout(() => {
                            jspreviewer.$refs.jsprevieweriframe.forEach(iframe => {
                                iframe.contentWindow.window.onload = () => {
                                    iframe.contentWindow.postMessage(runProjectCmd, arr_assets);
                                };
                                iframe.contentWindow.postMessage(runProjectCmd, arr_assets);
                            });
                        }, 5);
                    }
                });
            }
        }
        window.Simulator = Simulator;
        UB_IDE.ensureExtComponent('subwindows', 'jspreviewer');
        UB_IDE.ensureExtComponent('lefttoolbox', 'jspreviewer_add');
        let messageHandler = {
            mousemove(evt) {
                let v = evt.data.arg;
                let win = evt.source;
                let w = windows.find(w => w.iframe.contentWindow === win);
                w.mousePosition = v;
            },
            msg(evt) {
                let msg = evt.data.arg;
                let win = evt.source;
                let w = windows.find(w => w.iframe.contentWindow === win);
                w.msg = msg;
            }
        };
        function receiveMessage(event) {
            let cmd = event.data.cmd;
            if (messageHandler[cmd]) {
                messageHandler[cmd](event);
            }
        }
        window.addEventListener("message", receiveMessage);

    });

})();